home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 March / EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso / earcd / grafica / amhelios / win_bmap.cpp < prev    next >
C/C++ Source or Header  |  1999-01-01  |  11KB  |  407 lines

  1. ////////////////////////////////////////////////////////////
  2. //
  3. //  WIN_BMAP.CPP - MS-Windows Bitmap Class
  4. //
  5. //  Version:    1.03A
  6. //
  7. //  History:    94/08/23 - Version 1.00A release.
  8. //              94/12/02 - General rewrite.
  9. //              94/12/16 - Version 1.01A release.
  10. //              95/02/05 - Version 1.02A release.
  11. //              95/03/23 - Added FlushBitmap function.
  12. //                       - Added string.h include directive.
  13. //              95/06/22 - Added rgb_flag and hpal checks to
  14. //                         Redisplay function.
  15. //              95/06/24 - Deleted GetPixel, SetPalPixel and
  16. //                         SetPixel functions.
  17. //              95/07/21 - Version 1.02B release.
  18. //              96/02/14 - Version 1.02C release.
  19. //              96/04/01 - Version 1.03A release.
  20. //
  21. //  Compilers:  Microsoft Visual C/C++ Professional V1.5
  22. //              Borland C++ Version 4.5
  23. //
  24. //  Author:     Ian Ashdown, P.Eng.
  25. //              byHeart Software Limited
  26. //              620 Ballantree Road
  27. //              West Vancouver, B.C.
  28. //              Canada V7S 1W3
  29. //              Tel. (604) 922-6148
  30. //              Fax. (604) 987-7621
  31. //
  32. //  Copyright 1994-1996 byHeart Software Limited
  33. //
  34. //  The following source code has been derived from:
  35. //
  36. //    Ashdown, I. 1994. Radiosity: A Programmer's
  37. //    Perspective. New York, NY: John Wiley & Sons.
  38. //
  39. //  It may be freely copied, redistributed, and/or modified
  40. //  for personal use ONLY, as long as the copyright notice
  41. //  is included with all source code files.
  42. //
  43. ////////////////////////////////////////////////////////////
  44.  
  45. #include <string.h>
  46. #include "win_bmap.h"
  47.  
  48. // Open bitmap
  49. BOOL WinBitmap::Open( int w, int h )
  50. {
  51.   FreeBitmap();     // Release current bitmap (if any)
  52.   FreePalette();    // Release logical palette (if any)
  53.  
  54.   width = w;
  55.   height = h;
  56.  
  57.   // Bitmap width must be multiple of DWORD (4 bytes) to
  58.   // avoid segmentation arithmetic problems with __huge
  59.   // pointers on 80x86 CPU
  60.   pal_scan = (DWORD) BM_WidthBytes(width);
  61.   rgb_scan = (DWORD) BM_WidthBytes(width * BM_RGB_BPP);
  62.  
  63.   // Calculate bitmap size
  64.   pal_size = pal_scan * (DWORD) height;
  65.   rgb_size = rgb_scan * (DWORD) height;
  66.  
  67.   if (AllocBitmap() == FALSE)   // Allocate bitmap
  68.   {
  69.     width = height = 0;
  70.     pal_scan = rgb_scan = (DWORD) 0L;
  71.     pal_size = rgb_size = (DWORD) 0L;
  72.  
  73.     return FALSE;
  74.   }
  75.  
  76.   InitDIB();    // Initialize DIB palette
  77.  
  78.   return TRUE;
  79. }
  80.  
  81. // Perform color quantization
  82. BOOL WinBitmap::QuantizeColors()
  83. {
  84.   if (Quantize() == FALSE)      // Quantize bitmap colors
  85.     return FALSE;
  86.  
  87.   if (AllocPalette() == FALSE)  // Create logical palette
  88.     return FALSE;
  89.  
  90.   InitDIB();    // Reinitialize DIB palette
  91.   
  92.   return TRUE;
  93. }
  94.  
  95. // Display device-independent bitmap (DIB)
  96. BOOL WinBitmap::Display( HDC hdc, POINT &pos, RECT &rect )
  97. {
  98.   int i;                // Loop index
  99.   WORD *ppal_index;     // Palette-relative index pointer
  100.  
  101.   if (hddb == NULL)
  102.   {
  103.     // Convert DIB to device-dependent bitmap
  104.     if (rgb_flag == FALSE)
  105.     {
  106.       // Select logical palette into device context
  107.       SelectPalette(hdc, hpal, FALSE);
  108.  
  109.       // Realize logical palette
  110.       RealizePalette(hdc);
  111.  
  112.       // Convert DIB color palette to logical palette-
  113.       // relative indices
  114.       ppal_index = (WORD *) bm_colors;
  115.       for (i = 0; i < num_colors; i++)
  116.         *ppal_index++ = (WORD) i;
  117.  
  118.       // Display palette-mapped bitmap
  119.       if ((hddb = CreateDIBitmap(hdc, &(bm_iheader),
  120.           CBM_INIT, (LPSTR) pbm, (BITMAPINFO *) &bm_iheader,
  121.           DIB_PAL_COLORS)) == NULL)
  122.         return FALSE;
  123.     }
  124.     else
  125.     {
  126.       // Display 24-bit RGB bitmap
  127.       if ((hddb = CreateDIBitmap(hdc, &(bm_iheader),
  128.           CBM_INIT, (LPSTR) pbm, (BITMAPINFO *) &bm_iheader,
  129.           DIB_RGB_COLORS)) == NULL)
  130.         return FALSE;
  131.     }
  132.   }
  133.  
  134.   // Display device-dependent bitmap
  135.   return DisplayDDB(hdc, pos, rect);
  136. }
  137.  
  138. // Repaint client area
  139. void WinBitmap::Redisplay( HWND hwnd )
  140. {
  141.   HDC hdc;              // Device context
  142.   HPALETTE holdpal;     // Previous palette handle
  143.  
  144.   if (rgb_flag == FALSE)        // 256-color display ?
  145.   {
  146.     if (hpal != NULL)           // Valid bitmap palette ?
  147.     {
  148.       hdc = GetDC(hwnd);        // Get device context handle
  149.  
  150.       // Select logical palette into device context
  151.       holdpal = SelectPalette(hdc, hpal, FALSE);
  152.  
  153.       RealizePalette(hdc);      // Update system palette
  154.  
  155.       // Restore previous logical palette
  156.       SelectPalette(hdc, holdpal, FALSE);
  157.  
  158.       ReleaseDC(hwnd, hdc);     // Release device context
  159.  
  160.       // Repaint client area
  161.       InvalidateRect(hwnd, NULL, TRUE);
  162.     }
  163.   }
  164. }
  165.  
  166. BOOL WinBitmap::Write( char *fname )
  167. {
  168.   HFILE hfile;  // File handle
  169.  
  170.   // Check for existing bitmap
  171.   if (pbm == NULL)
  172.     return FALSE;
  173.  
  174.   // Open the file
  175.   if ((hfile = _lcreat(fname, 0)) == HFILE_ERROR)
  176.     return FALSE;
  177.  
  178.   // Write the file header (member-by-member to avoid
  179.   // structure alignment problems with Win32)
  180.   _lwrite(hfile, (LPSTR) &(bm_file.bfType),
  181.       sizeof(bm_file.bfType));
  182.   _lwrite(hfile, (LPSTR) &(bm_file.bfSize),
  183.       sizeof(bm_file.bfSize));
  184.   _lwrite(hfile, (LPSTR) &(bm_file.bfReserved1),
  185.       sizeof(bm_file.bfReserved1));
  186.   _lwrite(hfile, (LPSTR) &(bm_file.bfReserved2),
  187.       sizeof(bm_file.bfReserved2));
  188.   _lwrite(hfile, (LPSTR) &(bm_file.bfOffBits),
  189.       sizeof(bm_file.bfOffBits));
  190.  
  191.   // Write the information header
  192.   _lwrite(hfile, (LPSTR) &(bm_iheader),
  193.       sizeof(BITMAPINFOHEADER));
  194.  
  195.   if (rgb_flag == FALSE)
  196.   {
  197.     SetDIBPalette();    // Initialize the DIB palette
  198.  
  199.     // Write the DIB palette
  200.     _lwrite(hfile, (LPSTR) bm_colors, sizeof(RGBQUAD) *
  201.         num_colors);
  202.  
  203.     // Write the palette-mapped bitmap
  204.     WriteBitmap(hfile, pal_size);
  205.   }
  206.   else
  207.   {
  208.     // Write the RGB bitmap
  209.     WriteBitmap(hfile, rgb_size);
  210.   }
  211.  
  212.   _lclose(hfile);       // Close the file
  213.  
  214.   return TRUE;
  215. }
  216.  
  217. void WinBitmap::Close()     // Close bitmap
  218. {
  219.   FreeBitmap();     // Release bitmap
  220.   FreePalette();    // Release logical palette
  221.  
  222.   width = height = 0;
  223.   pal_scan = rgb_scan = (DWORD) 0L;
  224.   pal_size = rgb_size = (DWORD) 0L;
  225. }
  226.  
  227. // Initialize DIB data
  228. void WinBitmap::InitDIB()
  229. {
  230.   // Initialize DIB file header
  231.   if (rgb_flag == TRUE)
  232.     bm_file.bfSize = (DWORD) (bm_file.bfOffBits + rgb_size);
  233.   else
  234.     bm_file.bfSize = (DWORD) (bm_file.bfOffBits + pal_size);
  235.   bm_file.bfOffBits = (DWORD) (sizeof(BITMAPFILEHEADER)
  236.       + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) *
  237.       num_colors);
  238.  
  239.   // Initialize DIB information header
  240.   bm_iheader.biWidth = width;
  241.   bm_iheader.biHeight = height;
  242.   bm_iheader.biClrUsed = num_colors;
  243.   bm_iheader.biClrImportant = num_colors;
  244.  
  245.   if (rgb_flag == TRUE)
  246.     bm_iheader.biBitCount = 24;
  247.   else
  248.     bm_iheader.biBitCount = 8;
  249. }
  250.  
  251. // Display device-dependent bitmap (DDB)
  252. BOOL WinBitmap::DisplayDDB( HDC hdc, POINT &pos, RECT
  253.     &rect )
  254. {
  255.   BOOL status = FALSE;  // Return status
  256.   HBITMAP holddb;       // Previous DDB bitmap handle
  257.   HDC hmemdc;           // Memory device context handle
  258.   
  259.   // Create memory device context
  260.   if ((hmemdc = CreateCompatibleDC(hdc)) != NULL)
  261.   {
  262.     // Select bitmap
  263.     if ((holddb = (HBITMAP) SelectObject(hmemdc, hddb)) !=
  264.         NULL)
  265.     {
  266.       // Copy bitmap from memory to display device
  267.       BitBlt(hdc, rect.left, rect.top, rect.right,
  268.           rect.bottom, hmemdc, pos.x, pos.y, SRCCOPY);
  269.  
  270.       // Select previous bitmap
  271.       SelectObject(hmemdc, holddb);
  272.  
  273.       status = TRUE;
  274.     }
  275.  
  276.     // Delete memory device context
  277.     DeleteDC(hmemdc);
  278.   }
  279.  
  280.   return status;
  281. }
  282.  
  283. // Set device-independent bitmap (DIB) palette
  284. void WinBitmap::SetDIBPalette()
  285. {
  286.   int i;    // Loop index
  287.  
  288.   for (i = 0; i < num_colors; i++)
  289.   {
  290.     bm_colors[i].rgbRed = palette[i].GetRed();
  291.     bm_colors[i].rgbGreen = palette[i].GetGreen();
  292.     bm_colors[i].rgbBlue = palette[i].GetBlue();
  293.     bm_colors[i].rgbReserved = (BYTE) 0;
  294.   }
  295. }
  296.  
  297. // Write bitmap to file
  298. BOOL WinBitmap::WriteBitmap( int hfile, DWORD size )
  299. {
  300.   DWORD remain = size;          // Bytes remaining
  301.   BYTE __huge *pbuff = pbm;     // Buffer pointer
  302.  
  303.   // Write buffer to file in blocks
  304.   while (remain > (DWORD) BM_BlockSize)
  305.   {
  306.     if (_lwrite(hfile, (LPSTR) pbuff, BM_BlockSize) !=
  307.         BM_BlockSize)
  308.       return FALSE;
  309.     remain -= BM_BlockSize;
  310.     pbuff += BM_BlockSize;
  311.   }
  312.  
  313.   // Write last block to file
  314.   if ((DWORD) _lwrite(hfile, (LPSTR) pbuff, (WORD) remain)
  315.       == remain)
  316.     return TRUE;
  317.   else
  318.     return FALSE;
  319. }
  320.  
  321. void WinBitmap::FlushBitmap()   // Clear bitmap
  322. {
  323.   int i;                // Loop index
  324.   BYTE __huge *prow;    // Row pointer
  325.  
  326.   // Initialize row pointer
  327.   prow = pbm;
  328.  
  329.   for (i = 0; i < height; i++)
  330.   {
  331.     memset(prow, '\0', (size_t) rgb_scan);
  332.     prow += rgb_scan;
  333.   }
  334. }
  335.  
  336. BOOL WinBitmap::AllocBitmap()   // Allocate bitmap
  337. {
  338.   // Allocate global memory for bitmap
  339.   if ((hdib = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,
  340.       rgb_size)) != NULL)
  341.   {
  342.     // Lock bitmap memory
  343.     pbm = (BYTE __huge *) GlobalLock(hdib);
  344.     return TRUE;
  345.   }
  346.   else
  347.     return FALSE;
  348. }
  349.  
  350. BOOL WinBitmap::AllocPalette()  // Allocate logical palette
  351. {
  352.   int i;                // Loop index
  353.   LOGPALETTE *ppal;     // Logical palette pointer
  354.  
  355.   // Allocate palette
  356.   if ((ppal = (LOGPALETTE *) new BYTE[sizeof(LOGPALETTE)
  357.       + num_colors * sizeof(PALETTEENTRY)]) == NULL)
  358.     return FALSE;
  359.  
  360.   // Initialize palette information
  361.   ppal->palVersion = 0x300;
  362.   ppal->palNumEntries = num_colors;
  363.  
  364.   // Copy DIB palette
  365.   for (i = 0; i < num_colors; i++)
  366.   {
  367.     ppal->palPalEntry[i].peRed = palette[i].GetRed();
  368.     ppal->palPalEntry[i].peGreen = palette[i].GetGreen();
  369.     ppal->palPalEntry[i].peBlue = palette[i].GetBlue();
  370.     ppal->palPalEntry[i].peFlags = (BYTE) 0;
  371.   }
  372.  
  373.   // Create logical color palette
  374.   hpal = CreatePalette(ppal);
  375.  
  376.   delete [] ppal;       // Release palette memory
  377.  
  378.   return TRUE;
  379. }
  380.  
  381. void WinBitmap::FreeBitmap()    // Release bitmap
  382. {
  383.   if (hdib != NULL)     // Release DIB memory
  384.   {
  385.     GlobalUnlock(hdib);
  386.     GlobalFree(hdib);
  387.     pbm = NULL;
  388.     hdib = NULL;
  389.   }
  390.  
  391.   if (hddb != NULL)     // Release DDB memory
  392.   {
  393.     DeleteObject(hddb);
  394.     hddb = NULL;
  395.   }
  396. }
  397.  
  398. void WinBitmap::FreePalette()   // Release logical palette
  399. {
  400.   if (hpal != NULL)
  401.   {
  402.     DeleteObject(hpal);
  403.     hpal = NULL;
  404.   }
  405. }
  406.  
  407.